<template>
  <el-dialog title="制作节目清单"  width="90%" style="width: 800px;"  v-model="isVisible" @close="onCancelModel" :close-on-click-modal="false" destroy-on-close append-to-body>
    <div class="yy-template-file_setting">
      <div class="yy-template-file_setting-item">
        <label><span style="color:red;">*</span>节目名称:</label>
        <span style="flex: 1; min-width: 0;"><el-input v-model="settings.name" style="min-width: 120px;"/></span>
      </div>

      <div  class="yy-template-file_setting-item">
        <label>节目资源:</label>
        <span style="flex: 1; min-width: 0; ">
          <div class="yy-template-file">
            <div class="yy-template-file_item" v-for="form in settings.forms" :key="form.id">
              <div class="yy-template-file_item-resource">
                <div class="yy-template-file_item-resource-file">
                  <el-tree-select
                      v-if="isVisible && form.isNew"
                      v-model="form.fileViewId"
                      lazy
                      filterable
                      node-key="value"
                      :load="load"
                      :props="props"
                      style="flex:1;"
                      @change="onSelectResource(form)"
                  >
                    <template #default="{ data: { label, isLeaf } }">
                      <span>
                        <el-icon v-if="!isLeaf"><Folder /></el-icon>
                        <el-icon v-else><Document /></el-icon>
                      </span>
                      <span>{{ label }}</span>
                    </template>
                  </el-tree-select>
                  <span v-else>{{form.fileName}}</span>
                </div>
                <div class="yy-template-file_item-action">
                  <label style="margin: 10px;">共{{form.imageList?.length || 0}}页</label>
                  <span v-if="settings.forms.length > 1" class="yy-template-file_item-action--item yy-template-file_item-action--del" @click="onRemoveItem(form.id)"><el-icon ><Remove /></el-icon></span>
                  <span class="yy-template-file_item-action--item yy-template-file_item-action--add" @click="onAddSelectItem(form.id)"><el-icon ><CirclePlus /></el-icon></span>
                </div>
              </div>
              <div class="yy-template-file_item-setting">
                <div class="yy-template-file_item-setting-header" style="display: flex; justify-content: space-between;">
                    <label>
                        <span>时间周期：</span>
                        <el-date-picker
                            size="small"
                            v-model="form.schedule.range"
                            type="daterange"
                            range-separator="-"
                            start-placeholder="开始日期"
                            end-placeholder="结束日期"
                            @change="onGenerateSchedule(form)"
                        />
                    </label>
                    <label>
                        <span>时间间隔：</span>
                        <span>
                          <el-select size="small" v-model="form.schedule.type" placeholder="类型" style="width: 60px" @change="onIntervalTypeChange(form)">
                            <el-option label="天" value="date" />
                            <el-option label="时" value="hour" />
                            <el-option label="分" value="minute" />
                          </el-select>
                          <el-select size="small" v-model="form.schedule.value" placeholder="时长"  style="width: 80px" @change="onGenerateSchedule(form)">
                            <el-option v-for="interval in typeIntervalMap[form.schedule.type]" :label="interval" :value="interval"/>
                          </el-select>
                        </span>
                    </label>
                </div>
                <WidgetTable
                    :is-loading="table.isLoading"
                    :columns="table.columns"
                    :data="form.tableData"
                    :options="table.options"
                    :formats="table.formats"
                    :paging-data="table.paging"
                >
                      <template v-slot:page="{row, column}">
                          <div style="display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;">
                            <el-select v-model="row.page">
                              <el-option v-for="(img, index) in form.imageList" :key="img" :value="img" :label="'第'+(index + 1) + '页'"></el-option>
                            </el-select>
                          </div>
                      </template>
                      <template v-slot:startTime="{row, column}">
                        <div style="display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;">
                          <el-date-picker
                              v-model="row.startTime"
                              format="YYYY-MM-DD HH:mm"
                              date-format="YYYY-MM-DD"
                              time-format="HH:mm"
                              type="datetime"
                          />
                        </div>
                      </template>
                      <template v-slot:endTime="{row, column}">
                        <div style="display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;">
                          <el-date-picker
                              v-model="row.endTime"
                              format="YYYY-MM-DD HH:mm"
                              date-format="YYYY-MM-DD"
                              time-format="HH:mm"
                              type="datetime"
                          />
                        </div>
                      </template>
                    </WidgetTable>
              </div>
            </div>
          </div>
        </span>
      </div>
      <div class="yy-template-file_setting-item" v-if="false">
        <label>循环播放:</label>
        <span style="flex: 1; min-width: 0;">
           <el-radio-group v-model="settings.isLoop">
            <el-radio :value="1">是</el-radio>
            <el-radio :value="0">否</el-radio>
          </el-radio-group>
           <span style="margin-left: 10px; color: #aaa;">循环播放，将自动按照当前设置的时间周期和每页显示的时间来计算下一个播放周期。</span>
        </span>
      </div>
      <div class="yy-template-file_setting-item">
        <label>发布设备:</label>
        <span style="flex: 1; min-width: 0;">
           <el-select v-model="settings.deviceCodes" placeholder="请选择要发布的设备" clearable multiple style="min-width: 200px;">
            <el-option v-for="option in devices" :label="option.name + `(${option.code})`" :value="option.code" :key="option.code"/>
          </el-select>
        </span>
      </div>

    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="onCancelModel">取消</el-button>
        <el-button type="primary" @click="onSaveProgram">{{settings.deviceCodes?.length ? '一键发布' : '保存节目'}}</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import {defineExpose, defineEmits, nextTick, onBeforeMount, reactive, ref} from "vue";
import {useRouter} from "vue-router";
import ResourceApi from "@/api/broadcast/resource";
import DeviceApi from "@/api/queue/DeviceApi";
import TemplateApi from "@/api/broadcast/template";
import {BcTemplateModel} from "@/model/BcTemplateModel";
import {ResourceStatusMap} from "@/model/ResourceModel";
import WidgetTable from "@/components/widget/WidgetTable.vue";
import {ElMessage, ElSelect} from "element-plus";
import {TableColumn} from "@/model/Definition";
import {formatDate} from "@/utils";
const startTimeDefault = new Date(2000, 1, 1, 0, 0 , 0)
const endTimeDefault = new Date(2000, 1, 1, 23, 59 , 59)

const $emit = defineEmits({
  addSuccess: (data) => data
})
const router = useRouter()
const isVisible = ref(false)
let originData = null
let currentDeptId = null

const props = {
  label: 'label',
  children: 'children',
  isLeaf: 'isLeaf',
}

const typeIntervalMap = {
  'date': [1, 2, 3, 5, 7, 10, 14, 30],
  'hour': [1, 6, 12, 24],
  'minute': [2, 5, 15, 30, 60]
}

const settings = ref({
  name: '',
  deviceCodes: [],
  isLoop: 0,
  forms: [
    {
      id: 's' + getRowId(),
      isNew: true,
      schedule: {
        range: [],
        type: 'date',
        value: 1
      },
      fileViewId: '',
      fileName: '',
      imageList: [],
      tableData: []
    }
  ]
})

const table = reactive<{
  isLoading: boolean,
  paging: any,
  columns: TableColumn[],
  options?: any,
  formats?: any
}>({
  isLoading: false,
  columns: [
    {
      "field":"page",
      "label":"页面",
      "showable":true,
    },
    {
      "field":"startTime",
      "label":"开始时间",
      "showable":true,
      "width": 180
    },
    {
      "field":"endTime",
      "label":"结束时间",
      "showable":true,
      "width": 180
    }
  ],
  paging: {
    isPaging: false,
  },
  options: {
    highlight: true
  },
  formats: {
    'startTime': {
      slot: 'startTime',

    },
    'endTime': {
      slot: 'endTime',

    },
    'page': {
      slot: 'page'
    }
  }
})

const originForms = ref([])
const devices = ref([])

const load = (node, resolve) => {
  if (node.isLeaf) return resolve([])
  ResourceApi.listFile(node ? node.data.fileId : null, currentDeptId,null, 1, 10000).then((res) => {
    const files = res.rows? res.rows.map(item => {
      let label = item.fileName
      const status = ResourceStatusMap.find(r => r.value === +item.resState)
      if (item.resCategory === 2) {
        if (['1', '2'].includes(item.resState)) {
          label += `(${status.label})`
        }
      }
      return {
        label: label,
        value: item.viewKey + "__" + item.fileName + "__" + item.fileType + "__" + item.resId,
        fileId: item.resId,
        fileType: item.fileType,
        disabled: +item.resCategory === 1 || +status.value != 3,
        imageListUrl: item.imageListUrl,
        isLeaf: +item.resCategory === 2,
        children: +item.resCategory === 2 ? undefined : []
      }
    }) : []
    resolve(files)
  })
}

const onSelectResource = (form) => {
  const vieIdAndFileName = form.fileViewId.split('__')
  ResourceApi.listConvertData(vieIdAndFileName[3]).then((convertData) => {
    form.imageList = convertData
    form.tableData = convertData.map((item, index) => Object.assign({
      page: item,
      startTime: null,
      endTime: null
    }))
  })
}

const listDevice = () => {
  DeviceApi.listDevice(null, null, null, 1, 999).then((res) => {
    devices.value = res.data
  })
}


const onShowDialog = (deptId: string, data: BcTemplateModel) => {
  currentDeptId = deptId
  isVisible.value = true
  listDevice()

  if (data) {
    originData = data
    const config = data.config ? JSON.parse(data.config) : {}
    settings.value = Object.assign({
      name: data.name,
      deviceCodes: config.deviceCodes,
      isLoop: config.isLoop,
      forms: config.files ? config.files.map(item => {
        return {
          isNew: false,
          schedule: {
            range: [],
            type: 'date',
            value: 1
          },
          fileViewId: item.fileViewId,
          fileName: item.fileName,
          imageList: item.dataList.map(data => data.page),
          tableData: item.dataList.map(data => data)
        }
      }) : []
    })
    originForms.value = config.files
  }
}

function getRowId() {
  return new Date().getTime() + '_' + Math.random()
}

const onCancelModel = () => {
  isVisible.value = false
  originData = null
  originForms.value = []
  devices.value = []
  settings.value = {
    name: '',
    deviceCodes: [],
    isLoop: 0,
    forms: [
      {
        id: 's' + getRowId(),
        isNew: true,
        schedule: {
          range: [],
          type: 'date',
          value: 1
        },
        fileViewId: '',
        fileName: '',
        imageList: [],
        tableData: []
      }
    ]
  }
}

const onSaveProgram = () => {
  if(!settings.value.name) {
    ElMessage.warning("请输入节目名称")
    return
  }
  const newDataArr = settings.value.forms
      .filter(item => !!item.fileViewId)
      .map(item => {
        const vieIdAndFileName = item.fileViewId.split('__')
        return {
          fileViewId: item.fileViewId,
          fileName: vieIdAndFileName[1],
          dataList: item.tableData.map(data => ({
            page: data.page,
            startTime: data.startTime ? typeof data.startTime === 'number' ? data.startTime : data.startTime.getTime() : null,
            endTime:  data.endTime ? typeof data.endTime === 'number' ? data.endTime : data.endTime.getTime() : null,
          }))
        }
      })
  const data = Object.assign({}, settings.value, {
    deptId: currentDeptId,
    id: originData?.id || undefined,
    type: 'time',
    files: newDataArr
  })

  TemplateApi.saveTemplateByFile(data).then((res) => {
    $emit('addSuccess', res)
    onCancelModel()
  })
}


const onAddSelectItem = (id: string) => {
  const index = settings.value.forms.findIndex(item => item.id === id)
  settings.value.forms.splice(index + 1, 0, {
    id: 's' + getRowId(),
    isNew: true,
    schedule: {
      range: [],
      type: 'date',
      value: 1
    },
    fileViewId: '',
    fileName: '',
    imageList: [],
    tableData: []
  })
}

const onRemoveItem = (id: string) => {
  const index = settings.value.forms.findIndex(item => item.id === id)
  if (index >= 0) {
    settings.value.forms.splice(index, 1)
  }
}

const onIntervalTypeChange = (form) => {
  if (form.schedule.type === 'date') {
    form.schedule.value = 1
  } else if(form.schedule.type === 'hour') {
    form.schedule.value = 12
  } else {
    form.schedule.value = 30
  }
  onGenerateSchedule(form)
}

const onGenerateSchedule = (form) => {
  if (form.schedule.range?.length && form.schedule.type && form.schedule.value) {
    let data = []
    const startDateTime = new Date(form.schedule.range[0].getFullYear(), form.schedule.range[0].getMonth(), form.schedule.range[0].getDate(), 0, 0, 0).getTime()
    const endDateTime = new Date(form.schedule.range[1].getFullYear(), form.schedule.range[1].getMonth(), form.schedule.range[1].getDate(), 23, 59, 59).getTime()

    // 按天
    if (form.schedule.type === 'date') {
      data = _getDateRange(new Date(startDateTime), new Date(endDateTime), form)
    }
    // 按小时
    else if (form.schedule.type === 'hour') {
      data = _getHoursRange(new Date(startDateTime), new Date(endDateTime), form)
    }
    else {
      data = _getMinutesRange(new Date(startDateTime), new Date(endDateTime), form)
    }
    form.tableData = data
    console.log('data:', data)
  }
}


const _getMinutesRange = (startDate: Date, endDate: Date, form) => {
  let dates = form.imageList ? form.imageList .map((item, index) => Object.assign({
    page: item,
    startTime: null,
    endTime: null
  })) : [];
  let currentDate = startDate;
  let index = -1;
  while (currentDate <= endDate) {
    index += 1
    let start = new Date(currentDate.getTime());
    let hours = start.getHours()
    let minute = start.getMinutes()

    currentDate.setMinutes(currentDate.getMinutes() + +form.schedule.value);
    let endHours = currentDate.getHours()
    let endMinute = currentDate.getMinutes()

    if (dates?.length && dates[index]) {
      dates[index] = Object.assign({}, dates[index], {
        startDate: formatDate(start.getTime(), 'YYYY-MM-DD'),
        endDate: formatDate(currentDate.getTime(), 'YYYY-MM-DD'),
        start: String(hours).padStart(2, '0') + ':'+String(minute).padStart(2, '0'),
        end: String(endHours).padStart(2, '0') + ':'+String(endMinute).padStart(2, '0'),
        startTime: new Date(formatDate(start.getTime(), 'YYYY-MM-DD') + " " + String(hours).padStart(2, '0') + ':'+String(minute).padStart(2, '0') + ":00").getTime(),
        endTime: new Date(formatDate(currentDate.getTime(), 'YYYY-MM-DD') + " " + String(endHours).padStart(2, '0') + ':'+String(endMinute).padStart(2, '0') + ":59").getTime(),
      })
    }
  }
  if (dates && index < dates.length - 1) {
    for (let i = index + 1; i < dates.length; i++) {
      dates[i] = Object.assign({}, dates[i], {
        startDate: null,
        endDate: null,
        start: '00:00',
        end: '23:59',
        startTime: null,
        endTime: null,
      })
    }
  }
  return dates
}


const _getHoursRange = (startDate: Date, endDate: Date, form) => {
  let dates = form.imageList ? form.imageList .map((item, index) => Object.assign({
    page: item,
    startTime: null,
    endTime: null
  })) : [];
  let currentDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate(),startDate.getHours(), 0, 0);
  let index = -1;
  while (currentDate <= endDate) {
    index += 1;
    let start = new Date(currentDate.getTime());
    let hours = start.getHours()
    currentDate.setHours(currentDate.getHours() + +form.schedule.value);
    let end  = new Date(currentDate.getTime())
    end.setSeconds(end.getSeconds() - 1);
    if (dates?.length && dates[index]) {
      dates[index] = Object.assign({}, dates[index], {
        startDate: formatDate(start.getTime(), 'YYYY-MM-DD'),
        endDate: formatDate(end.getTime(), 'YYYY-MM-DD'),
        start: String(hours).padStart(2, '0') + ':00',
        end: String(end.getHours()).padStart(2, '0') + ':59',
        startTime: new Date(formatDate(start.getTime(), 'YYYY-MM-DD') + " " + String(hours).padStart(2, '0') + ':00:00').getTime(),
        endTime: new Date(formatDate(end.getTime(), 'YYYY-MM-DD') + " " + String(end.getHours()).padStart(2, '0') + ':59:59').getTime(),
      })
    }
  }
  if (dates && index < dates.length - 1) {
    for (let i = index + 1; i < dates.length; i++) {
      dates[i] = Object.assign({}, dates[i], {
        startDate: null,
        endDate: null,
        start: '00:00',
        end: '23:59',
        startTime: null,
        endTime: null,
      })
    }
  }
  return dates
}

const _getDateRange = (startDate: Date, endDate: Date, form) => {
  let dates = form.imageList ? form.imageList .map((item, index) => Object.assign({
    page: item,
    startTime: null,
    endTime: null
  })) : [];
  let currentDate = startDate;
  let index = -1;
  while (currentDate <= endDate) {
    index += 1
    let start = new Date(currentDate.getTime());
    currentDate.setDate(currentDate.getDate() + +form.schedule.value);
    let end = new Date(currentDate.getTime());
    if (currentDate > endDate) {
      end = endDate
    }
    end.setSeconds(end.getSeconds() - 1)
    if (dates?.length && dates[index]) {
      dates[index] = Object.assign({}, dates[index], {
        startDate: formatDate(start.getTime(), 'YYYY-MM-DD'),
        endDate: formatDate(end.getTime(), 'YYYY-MM-DD'),
        start: '00:00',
        end: '23:59',
        startTime: new Date(formatDate(start.getTime(), 'YYYY-MM-DD') + " " + "00:00:00").getTime(),
        endTime: new Date(formatDate(end.getTime(), 'YYYY-MM-DD') + " " + "23:59:59").getTime(),
      })
    }
  }
  if (dates && index < dates.length - 1) {
    for (let i = index + 1; i < dates.length; i++) {
      dates[i] = Object.assign({}, dates[i], {
        startDate: null,
        endDate: null,
        start: '00:00',
        end: '23:59',
        startTime: null,
        endTime: null,
      })
    }
  }
  return dates
}

defineExpose({
  onShowDialog
})
</script>
<style scoped lang="scss">
  .yy-template-file {
    width: 100%;
    height: 100%;
    border: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    &_title {
      width: 100%;
      font-size: 18px;
    }

    &_item {
      margin-bottom: 15px;
      width: 100%;
      &-resource {
        display: flex;
        flex-direction: row;
        & > div {
          display: inline-flex;
          align-items: center;
        }
        & > &-file {
          flex: 1;
          min-width: 100px;
        }
      }
      &-action {
        cursor: pointer;
        font-size: 16px;
        &--item {
          display: inline-flex;
          align-items: center;
          justify-content: center;
          padding: 5px 2px;
        }
        &--del {
          color: #e81123;
          margin-right: 8px;
        }
        &--add {
          color: #009688;
        }
      }
      &-setting {
        margin: 10px 0;
        border: 1px solid #d1d1d1;
        border-radius: 4px;
        max-height: 250px;
        overflow-y: auto;
        &-header {
          padding: 5px 15px;
        }
        &-item {
          margin: 5px 0;
          padding: 0 15px;
        }
      }
    }
    &_add {
      width: 100%;
      text-align: center;
    }
    &_setting {
      &-item {
        display: inline-flex;
        width: 100%;
        align-items: baseline;
        margin: 10px 0;
        & > label {
          margin-right: 8px;
        }
      }
    }
  }


</style>
